#!/usr/bin/ruby


#
# Math.acos marche pas
#

require 'thread'

def exit_error msg
  puts msg
  exit
end

def count_file_lines file
  count = `wc -l < #{file}`
  fail "wc failed: #{$?}" if $? != 0
  count.chomp!
end

def validate_files file1, file2
  nb_lines_1 = count_file_lines file1
  nb_lines_2 = count_file_lines file2
  if nb_lines_1 == nb_lines_2
	#puts "Nb of lines in files is ok\n"
  else
    exit_error "The files have not the same number of lines"
  end
end

def compute_wpow uv
  u = uv[0].to_f
  v = uv[1].to_f
  #puts "computing wpow for #{u} &  #{v}"
  # in knots
  wpow = Math.hypot(u, v)
  #puts "fin compute wpow"
  return wpow
end

def compute_wdir uv
  u = uv[0].to_f
  v = uv[1].to_f
  #puts "computing wdir for #{u} &  #{v}"
  # in degrees
  wdir = (180/Math::PI) * Math.atan(u/v)
  #puts "fin compute wdir"
  return wdir
end

if ARGV.size < 2
  exit_error "I need 2 existing files"
end
input1 = ARGV[0] if File.file?ARGV[1]
input2 = ARGV[1] if File.file?ARGV[1] 
if(input1==nil || input2==nil)
  exit_error "I need 2 existing files"
end

validate_files(input1, input2)

u_input_file = ""
v_input_file = ""

#read first line of each file to difereciate u file from v file
File.open(input1, "r") do |file1|
  headline = file1.gets
  if headline.include? "UGRD"
    u_input_file = input1
	#puts "U file: #{input1}"
  elsif headline.include? "VGRD"
    v_input_file = input1
	#puts "V file: #{input1}"
  end
end

headline = File.open(input2).readline
if headline.include? "VGRD"
  v_input_file = input2
  #puts "V file: #{input2}"
elsif headline.include? "UGRD"
  v_input_file = input2
  #puts "U file: #{input2}"
end
if v_input_file == "" || u_input_file == ""
  exit_error "I need a UGRD and a VGRD file"  
end

#input_files = ["UGRD_08012100.csv","VGRD_08012100.csv"]
input_files = [u_input_file,v_input_file]

output_file = 'output.csv'
out = File.new(output_file, "w")

shared_data = []
shared_line_id = 0
mutex_a = Mutex.new
mutex_b = Mutex.new
a = true;
b = false;
mutex = Mutex.new
threads = []

#puts "Launching parsing threads"
for file in input_files
  threads << Thread.new(file) { |myFile|
    i_am = ''
	#puts "Processing file #{myFile}"
    IO.foreach(myFile) { |line|
	  #Ignore first line of the file (column headers)
	  if line.include? "UGRD"
		#first line
		i_am = 'u'
		#puts "#{myFile} -- skipping line\t\t#{shared_line_id} -- #{line}"
		Thread.pass
		next 
	  end
	  if line.include? "VGRD"
		#first line
		i_am = 'v'
		#puts "#{myFile} -- skipping line\t\t#{shared_line_id} -- #{line}"
		Thread.pass
		next 
	  end
	  if ( i_am == 'u' )
		if ( a == true )
		  #puts "#{i_am} -- Processing line\t#{shared_line_id} -- #{line}"
		  my_columns = line.split(',')
		  #remove useless columns   
		  #line layout:
		  #+--+---+---+----+----+
		  #|0 | 1 | 2 | 3  | 4  |
		  #+--+---+---+----+----+
		  #|X | Y |lat|lng |vgrd|
		  #+--+---+---+----+----+
		  my_columns = my_columns.values_at(2,3,4)
		  #my_columns layout:
		  #+---+---+----+
		  #| 0 | 1 | 2  |
		  #+---+---+----+
		  #|lat|lng|vgrd|
		  #+---+---+----+
		  shared_data = my_columns
		  #puts "#{i_am} - #{shared_line_id} - PASSING #{shared_data}"
		  b = true
		  a = false
		  Thread.pass
		else
		  #puts "#{i_am} - REDO"
		  Thread.pass
		  redo
		end
	  end
	  if ( i_am == 'v' ) 
		if ( b == false )
		  #puts "#{i_am} - REDO"
		  Thread.pass
		  redo
		else
		  #puts "#{i_am} -- Processing line\t#{shared_line_id} -- #{line}"
		  my_columns = line.split(',')
		  #remove useless columns   
		  #line layout:
		  #+--+---+---+----+----+
		  #|0 | 1 | 2 | 3  | 4  |
		  #+--+---+---+----+----+
		  #|X | Y |lat|lng |vgrd|
		  #+--+---+---+----+----+
		  my_columns = my_columns.values_at(2,3,4)
		  #my_columns layout:
		  #+---+---+----+
		  #| 0 | 1 | 2  |
		  #+---+---+----+
		  #|lat|lng|vgrd|
		  #+---+---+----+
		  #insert other thread's columns in ours
		  #target layout:
		  #+--+---+---+-----+-----+----+----+
		  #|0 | 1 | 2 |  3  |  4  |  5 |  6 |
		  #+--+---+---+-----+-----+----+----+
		  #|id|lat|lng|w-pow|w-dir|ugrd|vgrd|
		  #+--+---+---+-----+-----+----+----+
		  #check that the lat/lng correspond
		  if my_columns.values_at(0, 1) == shared_data.values_at(0, 1)
			#insert line id
			my_columns.insert(0, shared_line_id)
			#puts "#{i_am} - #{shared_line_id} - MERGING #{my_columns}"
			#insert ugrd or vgrd at the right place
			if myFile == u_input_file
			  my_columns.insert(4, shared_data[2].chomp)
			else
			  my_columns.insert(3, shared_data[2].chomp)
			end
			#calculate w-pow and w-dir
			uv = my_columns.values_at(3, 4)
			#puts "uv = #{uv}"
			wpow = compute_wpow(uv)
			wdir = compute_wdir(uv)
			my_columns.insert(3, wpow.to_s)
			my_columns.insert(4, wdir.to_s)
			combined_line = my_columns.join(',')
			#puts "thread file #{myFile} merge shared_data: #{combined_line}"
			out << combined_line
		  else
			puts "#{my_columns.values_at(0, 1)}" 
			puts "#{shared_data.values_at(0, 1)}"
			exit_error "#{myFile} Mismatching lines at line #{shared_line_id}"
		  end
		  shared_data = ""
		  shared_line_id+=1
		  #puts "#{i_am} shared ++"
		  a = true
		  b = false
		  Thread.pass
		end
	  end
#      if shared_line_id == 10
#        puts "reached line 10 - exiting"
#        break
#      end
    }
  }
end

threads.each {|aThread| aThread.join }

puts "\nDone - #{shared_line_id + 1} entries processed.\n\n"


